import 'package:flutter/foundation.dart';
import 'package:flutter_pagewise/flutter_pagewise.dart';
import 'package:loxen/mode/like_bean.dart';
import 'package:loxen/mode/study/study_bean.dart';
import 'package:loxen/mode/study/study_info_bean.dart';
import 'package:loxen/mode/study/study_sub_category.dart';
import 'package:loxen/utils/string_res.dart';
import 'package:loxen/viewmode/base_view_model.dart';
import 'package:loxen/api/api.dart';
import 'package:rxdart/rxdart.dart';

import 'base_view_model.dart';

class StudyViewModel extends BaseViewModel {
  int currentCategory = 0;
  int currentCategoryId = 0;

  List<StudySubCategoryBean> _subCategoryBean = [];

  List<StudySubCategoryBean> get subCategoryBean => _subCategoryBean;

  List<String> types = ['knowledge', 'case'];

  Map<String, List<List<StudyInfo>>> _map = {};

  PagewiseLoadController<StudyInfo> pageController;

  StudyViewModel() {
    pageController = PagewiseLoadController<StudyInfo>(pageFuture: nextData, pageSize: 5);
  }

  void unCollection(StudyInfo entity, Function(String msg) onShow) {
    String type;
    if (currentCategory == 0) {
      type = 'study-knowledge';
    } else {
      type = 'study-case';
    }
    ApiService.unCollection(type, entity.id.toString()).listen((event) {
      if (event.statusCode == 200) {
        entity.is_collect = 0;
        entity.collect_num -= 1;
        onShow.call(StringResources.qu_xiao_shou_cang);
        notifyListeners();
      } else {
        onShow.call(StringResources.qu_xiao_shou_cang_shi_bai);
      }
    }, onError: (error, stack) {
      onShow.call(StringResources.wang_luo_yi_chang);
      print(error);
      print(stack);
    });
  }

  //点赞
  void like(StudyInfo entity) {
    if (entity != null) {
      if (entity.is_like == 0) {
        ApiService.likeStudy(entity.id.toString(), types[currentCategory])
            .flatMap((value) => compute(decodeLikeBean, value.data).asStream())
            .listen((event) {
          if (event.code == 2000) {
            entity.is_like = 1;
            entity.like_num = event.data.like_num;
            notifyListeners();
          }
        }, onError: (error) => print(error));
      } else {
        //取消点赞
        ApiService.unLikeStudy(entity.id.toString(), types[currentCategory])
            .flatMap((value) => compute(decodeLikeBean, value.data).asStream())
            .listen((event) {
          if (event.code == 2000) {
            entity.is_like = 0;
            entity.like_num = event.data.like_num;
            notifyListeners();
          }
        }, onError: (error) => print(error));
      }
    }
  }

  //刷新列表内容
  void refresh() {
    String key =
        '$currentCategory${_subCategoryBean[currentCategory].data.results[currentCategoryId].id}';
    if (_map.containsKey(key)) {
      _map[key].clear();
    }
    pageController.reset();
  }

  //一级分类切换
  void changeCategory(int index) {
    currentCategory = index;
    changeCategoryId(0);
    notifyListeners();
  }

  //二级分类切换
  void changeCategoryId(int index) {
    currentCategoryId = index;
    pageController.reset();
    notifyListeners();
  }

  //内容修改
  void changeEntity() {
    notifyListeners();
  }

  //下一页数据
  Future<List<StudyInfo>> nextData(int page) async {
    String key =
        '$currentCategory${_subCategoryBean[currentCategory].data.results[currentCategoryId].id}';
    String categoryId = _subCategoryBean[currentCategory].data.results[currentCategoryId].id;
    if (_map.containsKey(key)) {
      if (_map[key].length - 1 >= page) {
        return _map[key][page];
      } else {
        var data = await ApiService.studyList(
          types[currentCategory],
          categoryId,
          page + 1,
        ).flatMap((value) => compute(decodeStudyBean, value.data).asStream()).first;
        _map[key].add(data.data.results);
        return data.data.results;
      }
    } else {
      var data = await ApiService.studyList(types[currentCategory], categoryId, page + 1)
          .flatMap((value) => compute(decodeStudyBean, value.data).asStream())
          .first;
      _map.putIfAbsent(key, () => <List<StudyInfo>>[data.data.results]);
      return data.data.results;
    }
  }

  //加载数据
  void loadData() {
    if (mState == BaseState.LOADING) return;
    Rx.zip2<StudySubCategoryBean, StudySubCategoryBean, String>(
            _getSubCategoryBean(0), _getSubCategoryBean(1), (subCategory0, subCategory1) {
      if (subCategory0.code == 2000 && subCategory1.code == 2000) {
        _subCategoryBean.add(subCategory0);
        _subCategoryBean.add(subCategory1);
        String key = subCategory0.data.results[currentCategory].id;
        return key;
      }
      throw "类型请求失败！";
    })
        .doOnListen(() {
          mState = BaseState.LOADING;
          notifyListeners();
        })
        .flatMap((key) => _getStudyListBean(currentCategory, key))
        .listen((event) {
          if (event.code == 2000) {
            mState = BaseState.CONTENT;
            String key =
                '$currentCategory${_subCategoryBean[currentCategory].data.results[currentCategoryId].id}';
            _map.putIfAbsent(key, () => <List<StudyInfo>>[event.data.results]);
          } else {
            mState = BaseState.EMPTY;
          }
        }, onError: (error, stackTrace) {
          print(error);
          print(stackTrace);
          mState = BaseState.FAIL;
        }, onDone: () => notifyListeners());
  }

  Stream<StudyBean> _getStudyListBean(int type, String key) {
    return ApiService.studyList(types[type], key, 1)
        .flatMap((value) => compute(decodeStudyBean, value.data).asStream());
  }

  Stream<StudySubCategoryBean> _getSubCategoryBean(int type) {
    return ApiService.studySubCategory(types[type])
        .flatMap((value) => compute(decodeSubCategoryBean, value.data).asStream());
  }

  static LikeBean decodeLikeBean(dynamic json) {
    return LikeBean.fromJson(json);
  }

  static StudySubCategoryBean decodeSubCategoryBean(dynamic json) {
    return StudySubCategoryBean.fromJson(json);
  }

  static StudyBean decodeStudyBean(dynamic json) {
    return StudyBean.fromJson(json);
  }
}
